Bug 7132378

Bug Description:

This is a race bug.
The expected exception is a NullpointerException.
More details about this bug are at JDK-7132378 JIRA page.

Interleaving Description:

java.util.concurrent.FutureTask$Sync

t1  t2  V innerGet() throws InterruptedException, ExecutionException {
2           acquireSharedInterruptibly(0);
            if (getState() == CANCELLED)
                throw new CancellationException();
            if (exception != null)
                throw new ExecutionException(exception);
3           return result;
        }
        
        void innerSet(V v) {
            for (;;) {
                int s = getState();
                if (s == RAN)
                    return;
                if (s == CANCELLED) {
                    // aggressively release to set runner to null,
                    // in case we are racing with a cancel request
                    // that will try to interrupt runner
                    releaseShared(0);
                    return;
                }
    1           if (compareAndSetState(s, RAN)) {
    4               result = v;
                    releaseShared(0);
                    done();
                    return;
                }
            }
        }

Preconditions:
FuturnTask is not run.

a) thread 1 sets a value. It updates the task state to RAN at 1.
b) context switched, thread 2 acquires a continue signal at 2. The task state has been set to RAN at step a). So here thread 2 does not need to wait at 2.
c) thread 2 returns return that is null at 3.
d) context switched, thread 1 assigns a value to result. But unexpected null value has been returned at step c).

How To Reproduce:

This bug is reproduced under JDK 1.7.0.
It started at JDK 1.7.0, and has been fixed since JDK 1.7.0_40.
Execute the following scripts to run the test to reproduce the bug (assume the location of the jdk7 test project is jdk7_test_home).

Linux:
${jdk7_test_home}/scripts/7132378.sh [--javaloc path]
Windows:
%jdk7_test_home%\scripts\7132378.bat [--javaloc path]

Option Function
--javaloc The location of JDK that is eligible to reproduce the bug, if your java environment is not eligible.
In this case, it's JDK 1.7.0. It should be the absolute path to the JDK's java starter and ended with "/".
For example: ~/jdk/home/jdk1.7.0/bin/